package top.bulk.validator;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * InEnum注解的验证器，实现具体的注解功能
 *
 * @author 散装java
 * @version 1.0.0
 * @date 2024-06-10
 */
public class InEnumValidator implements ConstraintValidator<InEnum, Integer> {
    /**
     * 值数组
     */
    private Set<Integer> values;

    @Override
    public void initialize(InEnum constraintAnnotation) {
        IntArrayValuable[] values = constraintAnnotation.value().getEnumConstants();
        if (values.length == 0) {
            this.values = Collections.emptySet();
        } else {
            this.values = Arrays.stream(values[0].array()).boxed().collect(Collectors.toSet());
        }
    }

    /**
     * 检查给定的整数是否在预定义的集合内
     *
     * @param valueToValidate 待验证的整数
     * @param context         验证上下文，用于在验证失败时构建错误消息。
     * @return true如果值有效，否则返回false
     */
    @Override
    public boolean isValid(Integer valueToValidate, ConstraintValidatorContext context) {
        if (valueToValidate == null) {
            return false;
        }
        // 校验通过
        if (values.contains(valueToValidate)) {
            return true;
        }
        // 校验不通过，自定义提示语句（因为，注解上的 valueToValidate 是枚举类，无法获得枚举类的实际值）
        // 禁用默认的 message 的值
        context.disableDefaultConstraintViolation();
        // 重新添加错误提示语句
        context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()
                        .replaceAll("\\{value}", values.toString()))
                .addConstraintViolation();
        return false;
    }
}
